#include<iostream>
#include<cstdio>
#include<pthread.h>
#include<queue>
#include<vector>
#include<ctime>
#include<cstdlib>
#include<unistd.h>
#include<cstring>



//该类负责计算任务
template< class T>
class thread_cond{
public:
    thread_cond()
    {
        _consumer = PTHREAD_COND_INITIALIZER;
        _product = PTHREAD_COND_INITIALIZER;
    }

    void thread_cond_push(T data, pthread_mutex_t *mutex)
    {
        if (_buffer.size() >= _capacity)
        {   
            pthread_cond_wait(&_product, mutex);
        }
        _buffer.push(data);
        pthread_cond_signal(&_consumer); 
    }

    T thread_cond_get(pthread_mutex_t *mutex)
    {
        if (_buffer.size() <= 0)
        {
            pthread_cond_wait(&_consumer, mutex);
        }

        T rt_val = _buffer.front();
        _buffer.pop();
        pthread_cond_signal(&_product);
        return rt_val; 
    }

    ~thread_cond()
    {
        pthread_cond_destroy(&_consumer);
        pthread_cond_destroy(&_product);
    }

private:
    std::queue<T> _buffer;
    pthread_cond_t _consumer;
    pthread_cond_t _product;
    size_t _capacity = 100;
};



//该类负责存储数据
template<class T_save>
class Save{
public:
    Save()
    { 
        _file = fopen("data_store.txt", "r+");
        if (_file == NULL)
        {
            std::cout << "open file error" << std::endl;
            pthread_exit(NULL);
        } 
    }

    void data_store(T_save data)
    {
        char buff[_buff_cap];
        strcpy(buff, data.c_str());
        fwrite(buff, _buff_cap, _buff_cap-1, _file);
    }

    T_save data_read()
    {
        char buff[_buff_cap];
        fread(buff, _buff_cap, _buff_cap-1, _file);
        return buff;
    }

    ~Save() { fclose(_file); }

private:
    //std::queue<T_save> _save;
    //size_t _cap = 1000;
    size_t _buff_cap = 64;
    FILE *_file;
};


class task{
public:
    task(int x, int y, char op)
    :_num_x(x), _num_y(y), _operator(op)
    {}

    std::string operator()()
    {
        int rt_val = -1;
        switch(_operator)
        {
            case '+': rt_val = _num_y + _num_x; break;

            case '-': rt_val = _num_x - _num_y; break;

            case '*': rt_val = _num_x * _num_y; break;

            case '/': 
            {
                if(_num_y == 0) std::cout << "div zero error" << std::endl;
                else  rt_val = _num_x / _num_y; break;
            }

            case '%':
            {
                if(_num_y == 0) std::cout << "mod zero error" << std::endl;
                else  rt_val = _num_x % _num_y; 
                break;
            }

            default: std::cout <<"operator not support" << std::endl; break;
        }

        char buff[64];
        snprintf(buff, sizeof(buff)-1, "%d %c %d = %d", _num_x, _operator, _num_y, rt_val);
        std::cout <<"这是在处理函数内部， 处理结果：" << buff <<std::endl;
        return buff;
    }

    std::string task_name()
    {
        char buff[64];
        snprintf(buff, sizeof buff, "%d %c %d = ?", _num_x, _operator, _num_y);
        return buff;
    }

private:
    int  _num_x;
    int  _num_y;
    char _operator;
};

//该类为总类，分管计算任务和存储任务
template<class T1, class T2>
class cond_task{
public:

    void push(T1 data, pthread_mutex_t *mutex)
    {
        _cal.thread_cond_push(data, mutex);
    }

    T1 get(pthread_mutex_t *mutex)
    {
       return _cal.thread_cond_get(mutex);
    }

    void store_to_file(T2 data)
    {
        _store.data_store(data);
    }

    T2 read_from_file()
    {
        _store.data_read();
    } 

private:
    thread_cond<T1> _cal; 
    Save<T2> _store;
};





